/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/05/18
*/
#ifndef __EDUI_IENGINE_H__
#define __EDUI_IENGINE_H__

#include "../utilities/Singleton.h"
#include "../core/Msg.h"
#include "../core/SurfaceMgr.h"
#include "../core/StringMgr.h"
#include "../core/FontMgr.h"
#include "../core/CursorMgr.h"
#include "../core/WindowMgr.h"
#include "../external/tinyxml/tinyxml.h"

#ifdef EDUI_USE_LUAPLUS
    #include "../core/LuaMgr.h"
#endif

EDUI_NAMESPACE_BEGIN

#define IEnginePtr (IEngine::SingletonPtr())

//单例
class EDUI_API IEngine : public Singleton<IEngine>
{
public:
    IEngine();
    virtual ~IEngine();
public:
    virtual bool Init(const void* data1 = 0, const void* data2 = 0) = 0;
    virtual void Quit() = 0;
    virtual void PushMsg(Msg *msg) = 0;
    virtual void RunMsgLoop(float fps = -1) = 0;

    virtual IWindow*  GetWindowInterface() = 0;
    virtual ITexture* GetTextureInterface() = 0;
    virtual ISurface* GetSurfaceInterface() = 0;
    virtual IFont*    GetFontInterface() = 0;
    virtual ICursor*  GetCursorInterface() = 0;
    Control* GetControlInterface(const char* ctrlname);

    virtual const char* GetVersion();

    virtual bool SetClipboardText(const char* text) = 0;//clipboard text
    virtual char* GetClipboardText() = 0;
    virtual bool HasClipboardText() = 0;

    virtual IWindow* GetKeyFocusWindow() = 0;
    virtual IWindow* GetMouseFocusWindow() = 0;

    // 0 will set default cursor
    virtual void SetCursor(ICursor* cursor) = 0;
    virtual void ShowCursor(bool show) = 0;
    virtual bool IsCursorShow() = 0;

    virtual TimerID AddTimer(Uint32 interval, TimerCallback callback, IWindow* wnd = 0, void *data1 = 0, void *data2 = 0) = 0;
    virtual void RemoveTimer(TimerID id) = 0;
    virtual void RemoveTimer(IWindow *wnd) = 0;
public:
    SurfaceMgr* GetSurfaceMgr();
    FontMgr*    GetFontMgr();
    CursorMgr*  GetCursorMgr();
    StringMgr*  GetStringMgr();
    WindowMgr*  GetWindowMgr();
#ifdef EDUI_USE_LUAPLUS
    LuaMgr* GetLuaMgr();
    bool RunLua(const char* file);
#endif
    bool LoadFont(const char* file, int size, const char* name = 0, int id = -1);
    bool LoadFont(const char* file, int size, int style, const char* name = 0, int id = -1);
    bool LoadSurface(const char* file, const char* name = 0, int id = -1);
    bool LoadSurface(void* mem, int size, const char* name, int id = -1);
    bool LoadCursor(const char* surfaceName, int hotX, int hotY, const char* name, int id = -1);
    bool LoadCursor(SystemCursor sysid, const char* name, int id = -1);
    //load texture from surface to wnd.
    bool LoadTexture(IWindow* wnd, const char* surfaceName, const char* name = 0, int id = -1);
    bool LoadTexture(IWindow* wnd, size_t surfaceIndex, const char* name = 0, int id = -1);
    //load animation
    bool LoadAnimation(IWindow* wnd, const char* name, int id = -1);
    bool LoadAnimationFrame(IWindow* wnd, const char* name, const char* img, int id = -1);
    bool LoadAnimationFrame(IWindow* wnd, const char* name, int imgid, int id = -1);
    bool LoadAnimationFrame(IWindow* wnd, const char* name, AnimationFrame* frame, int id = -1);
    // load window from xml file/string
    IWindow* LoadWindow(const char* xmlfile, bool disableXmlDir = false);
    IWindow* LoadWindowFromStr(const char* xmlstr);
    bool LoadString(const char* name, const char* value, const char* group = 0, int id = -1);

    // load xml to load font,image,string
    bool LoadRes(const char* xmlfile, bool disableXmlDir = false);
    bool LoadResFromStr(const char* xmlstr);
    // load window layout from xml file
    bool LoadLayout(IWindow* wnd, const char* xmlfile, bool disableXmlDir = false);
    bool LoadLayoutFromStr(IWindow* wnd, const char* xmlstr);
    // load control from xml file/string
    Control* LoadControl(IWindow* wnd, const char* xmlfile, bool disableXmlDir = false);
    Control* LoadControlFromStr(IWindow* wnd, const char* xmlstr);

    void SetStringGroup(const char* group = 0);
    const char* GetStringGroup() const;
    // if not exit,return nilText
    const char* GetText(const char* name, const char* nilText = 0);
    const char* GetText(int id, const char* nilText = 0);

    //set xml files dir.<Include>label will be use it.if null,return current programm dir.
    void SetXmlDir(const char* dir);
    const char* GetXmlDir();

    // create a window
    IWindow* CreateWindow(const char* name, const char* title, int x, int y, int w, int h, Uint32 flags, int index = -1);
    
    void SetError(const char *fmt, ...);
    const char* GetError();
    void ClearError();

    IWindow* FindWindow(const char* name);
    IWindow* FindWindow(Uint32 wndID);
    IFont* FindFont(const char* name);
    IFont* FindFont(int id);
    ICursor* FindCursor(const char* name);
    ICursor* FindCursor(int id);
    ISurface* FindSurface(const char* name);
    ISurface* FindSurface(int id);
protected:
    // msg,return: if handled. 
    void DispatchMsg(Msg* msg);
private:
    bool _LoadRes(TiXmlDocument* xml);
    bool _BuildControl(Control** rootctrl, IWindow* wnd, Container* parent, TiXmlElement* root);
protected:
    SurfaceMgr m_surfaceMgr;
    FontMgr    m_fontMgr;
    CursorMgr  m_cursorMgr;
    StringMgr  m_stringMgr;
    WindowMgr  m_windowMgr;
#ifdef EDUI_USE_LUAPLUS
    LuaMgr m_luaMgr;
#endif

    char* m_stringGroup;
    char* m_xmlDir;
    String m_ver;
    String m_errmsg;
};

EDUI_NAMESPACE_END

#endif